#ifndef __CANYON_CORE_MEMORY
#define __CANYON_CORE_MEMORY

#include "arch.hpp"

namespace canyon{

class Memory{
    protected:
    uint8_t *pool;
    size_t   size;
    bool     locked = true;

    public:
    Memory(){
        this->pool   = nullptr;
        this->size   = 0;
        this->locked = true;
    }

    Memory(uint8_t * pool, size_t size){
        this->pool   = pool;
        this->size   = size;
        this->locked = false;
    }

    Memory(Memory & memory, size_t size=0, size_t bias=0){
        this->pool   = memory.pool + bias;
        if(size == 0){
            this->size = memory.size - bias;
        }else{
            this->size = size;
        }
        this->locked = false;
    }

    public:

    size_t max_size(){
        return this->size;
    }

    public:

    bool verify_read(size_t index){
        if(index<this->size && !this->locked){
            return true;  // 临时不作地址权限验证
        }else return false;
    }

    bool verify_write(size_t index){
        if(index<this->size && !this->locked){
            return true;  // 临时不作地址权限验证
        }else return false;
    }

    public:

    uint8_t get(size_t index){
        if(this->verify_read(index)){
            return this->pool[index];
        }else{
            // 异常回调中断，临时不作处理
            return 0;
        }
    }

    void set(size_t index, uint8_t value){
        if(this->verify_write(index)){
            this->pool[index] = value;
        }else{
            // 异常回调中断，临时不作处理
        }
    }

    void set_64(size_t index, uint64_t value){
        bool tmp = true;
        for(size_t i = 0; i<sizeof(uint64_t); i++){
            tmp = tmp && this->verify_write(index + i);
        }
        if(tmp){
            uint64_t *tmp_p = reinterpret_cast<uint64_t *>(this->pool + index);
            *tmp_p          = value;
        }else{
            // 异常回调中断，临时不作处理
        }
    }

    command get_command(size_t index){
        bool tmp = true;
        for(size_t i = 0; i<sizeof(command); i++){
            tmp = tmp && this->verify_read(index + i);
        }
        if(tmp){
            command *tmp_p = reinterpret_cast<command *>(this->pool + index);
            return  *tmp_p;
        }else{
            // 异常回调中断，临时不作处理
            return {};
        }
    }

    public:
    uint8_t * unsafe_get_adr(){
        if(this->locked){
            return nullptr;
        }
        return this->pool;
    }
};

}

#endif
